From 77699d42403ccfb0239423c615afcb51c8ccb2f0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 3 Feb 2009 18:12:51 +0000 Subject: [PATCH] Consolidate cpufreq cmdline handling ... by moving as much of the option processing into cpufreq code as is possible, by folding the cpufreq_governor option into the cpufreq one (the governor name, if any, must be specified as the first thing after the separator following "cpufreq=xen"), and by allowing each governor to have an option processing routine. Signed-off-by: Jan Beulich --- xen/common/domain.c | 14 ---- xen/drivers/cpufreq/cpufreq.c | 45 +++++++++++++ xen/drivers/cpufreq/cpufreq_ondemand.c | 93 ++++++++++++-------------- xen/include/acpi/cpufreq/cpufreq.h | 1 + 4 files changed, 87 insertions(+), 66 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index 339371a836..dbbc3e7d52 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -41,7 +41,6 @@ boolean_param("dom0_vcpus_pin", opt_dom0_vcpus_pin); /* set xen as default cpufreq */ enum cpufreq_controller cpufreq_controller = FREQCTL_xen; -struct cpufreq_governor *cpufreq_opt_governor; static void __init setup_cpufreq_option(char *str) { @@ -71,19 +70,6 @@ static void __init setup_cpufreq_option(char *str) } custom_param("cpufreq", setup_cpufreq_option); -static void __init setup_cpufreq_gov_option(char *str) -{ - if ( !strcmp(str, "userspace") ) - cpufreq_opt_governor = &cpufreq_gov_userspace; - else if ( !strcmp(str, "performance") ) - cpufreq_opt_governor = &cpufreq_gov_performance; - else if ( !strcmp(str, "powersave") ) - cpufreq_opt_governor = &cpufreq_gov_powersave; - else if ( !strcmp(str, "ondemand") ) - cpufreq_opt_governor = &cpufreq_gov_dbs; -} -custom_param("cpufreq_governor", setup_cpufreq_gov_option); - /* Protect updates/reads (resp.) of domain_list and domain_hash. */ DEFINE_SPINLOCK(domlist_update_lock); DEFINE_RCU_READ_LOCK(domlist_read_lock); diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c index dee38fa513..831bed639f 100644 --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -53,6 +53,7 @@ struct cpufreq_dom { }; static LIST_HEAD(cpufreq_dom_list_head); +struct cpufreq_governor *cpufreq_opt_governor; LIST_HEAD(cpufreq_governor_list); struct cpufreq_governor *__find_governor(const char *governor) @@ -467,3 +468,47 @@ out: return ret; } +void __init cpufreq_cmdline_parse(char *str) +{ + static struct cpufreq_governor *__initdata cpufreq_governors[] = + { + &cpufreq_gov_userspace, + &cpufreq_gov_dbs, + &cpufreq_gov_performance, + &cpufreq_gov_powersave + }; + + do { + char *val, *end = strchr(str, ','); + unsigned int i; + + if ( end ) + *end++ = '\0'; + val = strchr(str, '='); + if ( val ) + *val++ = '\0'; + + if ( !cpufreq_opt_governor ) + { + if ( !val ) + { + for ( i = 0; i < ARRAY_SIZE(cpufreq_governors); ++i ) + if ( !strcmp(str, cpufreq_governors[i]->name) ) + { + cpufreq_opt_governor = cpufreq_governors[i]; + str = NULL; + break; + } + } + else + cpufreq_opt_governor = CPUFREQ_DEFAULT_GOVERNOR; + } + + if ( str ) + for ( i = 0; i < ARRAY_SIZE(cpufreq_governors); ++i ) + if ( cpufreq_governors[i]->handle_option ) + cpufreq_governors[i]->handle_option(str, val); + + str = end; + } while ( str ); +} diff --git a/xen/drivers/cpufreq/cpufreq_ondemand.c b/xen/drivers/cpufreq/cpufreq_ondemand.c index 55c005932d..609540e477 100644 --- a/xen/drivers/cpufreq/cpufreq_ondemand.c +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c @@ -281,9 +281,50 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) return 0; } +static void __init cpufreq_dbs_handle_option(const char *name, const char *val) +{ + if ( !strcmp(name, "rate") && val ) + { + usr_sampling_rate = simple_strtoull(val, NULL, 0) * MICROSECS(1); + } + else if ( !strcmp(name, "threshold") && val ) + { + unsigned long tmp = simple_strtoul(val, NULL, 0); + + if ( tmp < MIN_FREQUENCY_UP_THRESHOLD ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified threshold too low, using %d\n", + MIN_FREQUENCY_UP_THRESHOLD); + tmp = MIN_FREQUENCY_UP_THRESHOLD; + } + else if ( tmp > MAX_FREQUENCY_UP_THRESHOLD ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified threshold too high, using %d\n", + MAX_FREQUENCY_UP_THRESHOLD); + tmp = MAX_FREQUENCY_UP_THRESHOLD; + } + dbs_tuners_ins.up_threshold = tmp; + } + else if ( !strcmp(name, "bias") && val ) + { + unsigned long tmp = simple_strtoul(val, NULL, 0); + + if ( tmp > 1000 ) + { + printk(XENLOG_WARNING "cpufreq/ondemand: " + "specified bias too high, using 1000\n"); + tmp = 1000; + } + dbs_tuners_ins.powersave_bias = tmp; + } +} + struct cpufreq_governor cpufreq_gov_dbs = { .name = "ondemand", .governor = cpufreq_governor_dbs, + .handle_option = cpufreq_dbs_handle_option }; static int __init cpufreq_gov_dbs_init(void) @@ -297,55 +338,3 @@ static void cpufreq_gov_dbs_exit(void) cpufreq_unregister_governor(&cpufreq_gov_dbs); } __exitcall(cpufreq_gov_dbs_exit); - -void __init cpufreq_cmdline_parse(char *str) -{ - do { - char *val, *end = strchr(str, ','); - - if ( end ) - *end++ = '\0'; - val = strchr(str, '='); - if ( val ) - *val++ = '\0'; - - if ( !strcmp(str, "rate") && val ) - { - usr_sampling_rate = simple_strtoull(val, NULL, 0) * MICROSECS(1); - } - else if ( !strcmp(str, "threshold") && val ) - { - unsigned long tmp = simple_strtoul(val, NULL, 0); - - if ( tmp < MIN_FREQUENCY_UP_THRESHOLD ) - { - printk(XENLOG_WARNING "cpufreq/ondemand: " - "specified threshold too low, using %d\n", - MIN_FREQUENCY_UP_THRESHOLD); - tmp = MIN_FREQUENCY_UP_THRESHOLD; - } - else if ( tmp > MAX_FREQUENCY_UP_THRESHOLD ) - { - printk(XENLOG_WARNING "cpufreq/ondemand: " - "specified threshold too high, using %d\n", - MAX_FREQUENCY_UP_THRESHOLD); - tmp = MAX_FREQUENCY_UP_THRESHOLD; - } - dbs_tuners_ins.up_threshold = tmp; - } - else if ( !strcmp(str, "bias") && val ) - { - unsigned long tmp = simple_strtoul(val, NULL, 0); - - if ( tmp > 1000 ) - { - printk(XENLOG_WARNING "cpufreq/ondemand: " - "specified bias too high, using 1000\n"); - tmp = 1000; - } - dbs_tuners_ins.powersave_bias = tmp; - } - - str = end; - } while ( str ); -} diff --git a/xen/include/acpi/cpufreq/cpufreq.h b/xen/include/acpi/cpufreq/cpufreq.h index eba0d7c6a4..93acc7a4e0 100644 --- a/xen/include/acpi/cpufreq/cpufreq.h +++ b/xen/include/acpi/cpufreq/cpufreq.h @@ -87,6 +87,7 @@ struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; int (*governor)(struct cpufreq_policy *policy, unsigned int event); + void (*handle_option)(const char *name, const char *value); struct list_head governor_list; }; -- 2.30.2